#include "ahxgwnet.h"
using namespace ahxgwnet;

void sigChld(int signo)
{
    pid_t   pid;
    int     stat;
    
    while ( (pid = wait(&stat)) > 0)
        printf("child %d die\n", pid);
    return;
}

void strEcho(int s)
{
    char        buf[MAXLINE];
    int         nRead;
    IOWrapper   iow(s);
    
    while ( (nRead = read(s, buf, sizeof(buf))) != 0)
    {
        if (nRead < 0)
        {
            if (errno == EINTR)
                continue;
            return;
        }
        iow.writeN(buf, nRead);
    }
}

int main()
{
    Socket  s, c;
    int     nReady, client[FD_SETSIZE];
    int     i, maxFd, maxI;
    fd_set  rSet, allSet;
    char    buf[MAXLINE];
    ssize_t n;
    
    
    s.setReuseAddress();
    if (!s.bind(8888))
        perror("bind error");
    if (!s.listen(10))
        perror("listen error");
    
    maxFd   = s.m_s;
    maxI    = -1;
    for (i = 0; i < FD_SETSIZE; i++)
        client[i] = -1;
    FD_ZERO(&allSet);
    FD_SET(s.m_s, &allSet);
    
    for ( ; ; )
    {
        rSet = allSet;
        nReady = select(maxFd + 1, &rSet, NULL, NULL, NULL);
        
        if (FD_ISSET(s.m_s, &rSet))
        {
            if (s.accept(c) == -1)
                perror("accept error");
            
            for (i = 0; i < FD_SETSIZE; i++)
                if (client[i] == -1)
                {
                    client[i] = c.m_s;
                    break;
                }
            if (i == FD_SETSIZE)
            {
                perror("too many clients");
                exit(1);
            }
            FD_SET(c.m_s, &allSet);
            if (c.m_s > maxFd)
                maxFd = c.m_s;
            if (i > maxI)
                maxI = i;
            
            if (--nReady <= 0)
                continue;
        }
        
        for (i = 0; i <= maxI; i++)
        {
            if (client[i] == -1 || !FD_ISSET(client[i], &rSet))
                continue;
            if ((n = read(client[i], buf, MAXLINE)) == 0)
            {
                close(client[i]);
                FD_CLR(client[i], &allSet);
                client[i] = -1;
            }
            else
            {
                fprintf(stderr, "write %d\n", n);
                IOWrapper   iow(client[i]);
                iow.writeN(buf, n);
            }

            if (--nReady <= 0)
                break;
        }
    }
}

/*
int main()
{
    Socket  s, c;
    Util    util;
    pid_t   childPid; 
    
    if (!s.bind(8888))
        perror("bind error");
    if (!s.listen(10))
        perror("listen error");
    util.signal(SIGCHLD, sigChld);
    
    for ( ; ; )
    {
        if ( s.accept(c) == -1)
            perror("accept error");
        
        if ( (childPid = fork()) == 0)
        {
            close(s.m_s);
            strEcho(c.m_s);
            exit(0);
        }
        close(c.m_s);
    }
    
    return 0;
}
*/
